import { Edge, Node, EdgeView, Cell } from "@antv/x6";
import { getNodeMaxId, getEdgeMaxId } from "@/utils/antvx6/nodeOrEdgeMaxId";
import { submitEdge } from "@/utils/antvx6/InsertNode";
import { NodePoint } from "@/utils/antvx6/nodePoint";
import { getSourceToTarget } from "@/utils/antvx6/realTimeCoordinate";
import { edgeLabels, edgeAttrs, edgeRouter } from "@/utils/antvx6/configurationDetails";
/**
 * 绘制路径
 * @param { HTMLElement }  elementGraph  antv x6 元素
 * @param { HTMLElement }  container  DOM 元素
 * @param { number }  mapId  地图id
 * @param { Number } Mode 单双行线
 */
// 目标源
let targets: any = "";
// 是否启用选中或点击节点进行串联
let selectedBool: boolean = false;
let lineMode: number = 1;

export const drawLine = (elementGraph: any, container: any, _width: number, _height: number, Mode: number) => {
  if (selectedBool) return;
  lineMode = Mode;
  selectedBool = true;
  let edge: Edge | null | any = null;
  let nodeOne: Node | null | any = null;
  const init = async (pos: { x: number; y: number }) => {
    // 处理重复的节点
    const sumNodeId = getNodeMaxId(elementGraph);
    // 提交的节点
    nodeOne = await nodeFn(elementGraph, sumNodeId, pos.x, pos.y);
    // 这是指引线条
    edge = elementGraph.addEdge({
      source: nodeOne,
      target: pos,
      zIndex: 0,
      router: edgeRouter(),
      attrs: {
        line: {
          stroke: "#FF8D1A",
          strokeWidth: 0.5,
          targetMarker: {
            size: 2,
          },
        },
      },
    });
    // 绘制路径时禁用框选
    elementGraph.disableSelection();
  };
  // 添加路径点
  const addVertices = (pos: { x: number; y: number }) => {
    if (edge) {
      edge.appendVertex(pos);
    }
  };
  // 移动所获取的坐标系
  const onMouseMove = (e: MouseEvent) => {
    if (edge) {
      const pos = elementGraph.clientToLocal(e.clientX, e.clientY);
      edge.setTarget(pos);
      const vertices = edge.getVertices();
      if (vertices.length >= 1) {
        const startPoint: any = vertices[vertices.length - 2] || nodeOne.position();
        const getSource: any = vertices[vertices.length - 1];
        const getTarget: any = pos;
        getSourceToTarget(getSource, getTarget, startPoint);
      }
    }
  };
  // 移除路径点
  const print = () => {
    if (edge) {
      const view = elementGraph.findViewByCell(edge) as EdgeView;
      const vertices = edge.getVertices();
      vertices.forEach((v, i) => {
        const vertexAtSum: number = i;
        view.cell.removeVertexAt(vertexAtSum, view.cell);
      });
      elementGraph.removeCell(view.cell);
    }
  };
  // 结束绘制路径点
  const finish = (closed: boolean) => {
    console.log(closed, "finish");
    if (nodeOne && edge) {
      const vertices = edge.getVertices();
      if (closed) {
        if (vertices.length >= 2) {
          const center = nodeOne.getBBox().center;
          edge.setSource(center);
          edge.setTarget(center);
          nodeOne = null;
          print();
        } else {
          elementGraph.removeCells([nodeOne, edge]);
          nodeOne = null;
          edge = null;
        }
      } else {
        if (vertices.length >= 1) {
          const center = nodeOne.getBBox().center;
          edge.setSource(center);
          edge.setTarget(vertices[vertices.length - 1]);
          nodeOne = null;
          print();
        } else {
          elementGraph.removeCells([nodeOne, edge]);
          nodeOne = null;
          edge = null;
        }
        closedLoop();
      }
      container.removeEventListener("mousemove", onMouseMove);
    } else {
      closedLoop();
    }
  };
  // 点击绘制节点
  elementGraph.on("blank:click", ({ x, y }) => {
    const xSum: number = Math.abs(x);
    const ySum: number = Math.abs(y);
    const widthGraph: number = Math.ceil(_width);
    const heightGraph: number = Math.ceil(_height);
    if (xSum > widthGraph || ySum > heightGraph || x < 0 || y < 0)
      return ElMessage.error(
        `您添加的画布节点【x坐标: ${x}】【y坐标: ${y}】已超出范围，规定范围是：${_width} * ${_height}内`
      );
    init({ x, y });
    container.addEventListener("mousemove", onMouseMove);
  });
  elementGraph.on("edge:click", async ({ x, y }) => {
    const xSum: number = Math.abs(x);
    const ySum: number = Math.abs(y);
    const widthGraph: number = Math.ceil(_width);
    const heightGraph: number = Math.ceil(_height);
    if (xSum > widthGraph || ySum > heightGraph || x < 0 || y < 0)
      return ElMessage.error(
        `您添加的画布节点【x坐标: ${x}】【y坐标: ${y}】已超出范围，规定范围是：${_width} * ${_height}内`
      );
    const nodes = elementGraph.getNodesFromPoint(x, y);
    if (nodes.length && nodes[0] === nodeOne) {
      finish(true);
    } else {
      addVertices({ x, y });
      // 处理重复的节点
      const sumValue: number = getNodeMaxId(elementGraph);
      // 提交的节点
      const model = await nodeFn(elementGraph, sumValue, x, y);
      const vertices = edge.getVertices();
      const edgeId = getEdgeMaxId(elementGraph);
      if (vertices.length === 1) {
        // 第一个节点的坐标 --- 绘制边
        edgeFn(elementGraph, edgeId, nodeOne, model);
      } else {
        // 绘制边
        edgeFn(elementGraph, edgeId, targets, model);
      }
    }
  });
  // 键盘删除结束绘制
  elementGraph.bindKey("Escape", () => {
    if (selectedBool) {
      // 取消连接桩磁体
      const nodeList = elementGraph.getNodes().filter((item: Cell) => item.shape === "node-point");
      nodeList.forEach((item: Cell) => item.prop("isShowPortMagnet", false));
      finish(false);
      getSourceToTarget(null, null, null);
      elementGraph.off("blank:click");
      elementGraph.off("edge:click");
      // 绘制完路径启用框选
      elementGraph.enableSelection();
    }
  });
  // 清空
  const closedLoop = () => {
    targets = "";
    selectedBool = false;
    elementGraph.unbindKey("Escape");
  };
  // 点击节点进行串联起来
  elementGraph.on("node:click", ({ node }) => {
    if (!node.id?.startsWith("n")) return;
    if (selectedBool) {
      if (node.id === targets?.id) return;
      // 处理重复的边
      const countsEdgeId = getEdgeMaxId(elementGraph);
      // 绘制边
      if (targets) {
        edgeFn(elementGraph, countsEdgeId, targets, node);
      } else {
        edgeFn(elementGraph, countsEdgeId, node, nodeOne);
      }
    }
  });
};
/**
 * 绘制路径 -- 提交节点
 * @param { HTMLElement }  elementGraph  antv x6 元素
 * @param { Number }  nodeIndex  节点索引
 * @param { Number }  x  x 坐标
 * @param { Number }  y  y 坐标
 */
const nodeFn = (elementGraph: any, nodeIndex: number, x: number, y: number) => {
  // 提交入参节点
  const nodeId = `n${nodeIndex}`;
  const nodeP = new NodePoint();
  const paramNodes = {
    nodeNameEn: nodeId,
    nodeNameCn: nodeId,
    hasDirection: 0,
    mapNodeType: 9,
    x: x,
    y: y,
  };
  nodeP.setData({
    id: nodeId,
    x: x,
    y: y,
    data: {
      x: x,
      y: y,
      hasDirection: paramNodes.hasDirection,
      mapNodeType: paramNodes.mapNodeType,
      nodeNameCn: paramNodes.nodeNameCn,
      nodeNameEn: paramNodes.nodeNameEn,
    },
  });
  const model: any = elementGraph.addNode(nodeP.getModel());
  if (model) {
    return model;
  }
};

/**
 * 绘制路径 -- 提交边
 * @param { HTMLElement }  elementGraph  antv x6 元素
 * @param { Number }  edgeIndex  边索引
 * @param { Object }  source  源节点或起始点
 * @param { Object }  target  目标节点或目标点
 */
const edgeFn = (elementGraph: any, edgeIndex: number, source: object, target: object) => {
  const idsEdge = `e${edgeIndex}`;
  if (!source || !target) return;
  targets = target;
  elementGraph.addEdge({
    id: idsEdge,
    source,
    target,
    zIndex: 0,
    data: {
      edgeType: 1,
      lineMode,
      edgeName: idsEdge
    },
    labels: edgeLabels(`e${edgeIndex}`),
    router: edgeRouter(),
    attrs: edgeAttrs(2, lineMode)
  });
  // 提交边
  submitEdge(elementGraph, idsEdge);
};
